<?php

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *	   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @package log4php
 */

/**
 * Contains various helper methods.
 *
 * @package log4php
 * @subpackage helpers
 * @since 2.3
 */
class LoggerUtils
{

    /**
     * Splits a fully qualified class name into fragments delimited by the
     * namespace separator (\).
     *
     *
     * For backward compatibility, a dot (.) can be used as a delimiter as
     * well.
     *
     * @param string $name            
     *
     * @return array Class name split into fragments.
     */
    public static function tokenizeClassName($name)
    {
        $name = str_replace('.', '\\', $name);
        $name = trim($name, ' \\');
        $fragments = explode('\\', $name);
        
        foreach ($fragments as $key => $fragment) {
            if (trim($fragment) === '') {
                unset($fragments[$key]);
            }
        }
        
        return $fragments;
    }

    /**
     * Attempts to shorten the given class name to the desired length.
     *
     * This is done by separating the class name into fragments (delimited
     * by \ or .) and trimming individual fragments, starting with the left,
     * until desired length has been reached.
     *
     * The final fragment (i.e. class name) will never be shortened so the
     * result may still be longer than given length.
     *
     * @param string $name
     *            The (qualified) class name.
     * @param integer $length
     *            The length to shorten to. If null or 0 is given,
     *            the name will be returned without shortening.
     */
    public static function shortenClassName($name, $length)
    {
        if ($length === null || $length < 0) {
            return $name;
        }
        
        $name = str_replace('.', '\\', $name);
        $name = trim($name, ' \\');
        
        // Check if any shortening is required
        $currentLength = strlen($name);
        if ($currentLength <= $length) {
            return $name;
        }
        
        // Split name into fragments
        $fragments = explode('\\', $name);
        
        // If zero length is specified, return only last fragment
        if ($length == 0) {
            return array_pop($fragments);
        }
        
        // If the name splits to only one fragment, then it cannot be shortened
        $count = count($fragments);
        if ($count == 1) {
            return $name;
        }
        
        foreach ($fragments as $key => &$fragment) {
            
            // Never shorten last fragment
            if ($key == $count - 1) {
                break;
            }
            
            // Check for empty fragments (shouldn't happen but it's possible)
            $fragLen = strlen($fragment);
            if ($fragLen <= 1) {
                continue;
            }
            
            // Shorten fragment to one character and check if total length
            // satisfactory
            $fragment = substr($fragment, 0, 1);
            $currentLength = $currentLength - $fragLen + 1;
            
            if ($currentLength <= $length) {
                break;
            }
        }
        unset($fragment);
        
        return implode('\\', $fragments);
    }
}

